package itsm.isperp.framework.upload.impl;

import itsm.isperp.framework.upload.UploadPreference;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.SystemUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * {@link UploadPreference}接口的默认实现.
 * <p>
 * 通过解析字符串或Properties对象中包含的文件上传属性信息,填充自身,并返回属性中包含的有效信息.
 * </p> 
 */
public class DefaultUploadPreferenceImpl implements UploadPreference {

	private static final long DEFAULT_MAX_SIZE = 10240000;
	public static final String STORE_KEY = "store";
	public static final String MAX_SIZE_KEY = "maxSize";
	public static final String ALLOWED_TYPES_KEY = "allowedTypes";

	public DefaultUploadPreferenceImpl(String preferenceDefintion) {
		Assert.notNull(preferenceDefintion);
		Properties uploadPreferenceProperties = stringToProperties(preferenceDefintion);
		this.uploadPreferenceProperties = uploadPreferenceProperties;
		this.parse();
	}

	public DefaultUploadPreferenceImpl(Properties uploadPreferenceProperties) {
		this.uploadPreferenceProperties = uploadPreferenceProperties;
		this.parse();
	}

	/**
	 * 从Properties中解析出文件储存位置等信息.
	 */
	protected void parse() {
		parseStore();
		parseMaxSize();
		parseAllowedTypes();
	}

	/**
	 * 解析允许上传的文件类型.
	 */
	protected void parseAllowedTypes() {
		String allowedTypesDef = this.uploadPreferenceProperties
				.getProperty(ALLOWED_TYPES_KEY);
		if (StringUtils.hasText(allowedTypesDef)) {
			this.allowedTypes = allowedTypesDef.split(",");
		}
	}

	/**
	 * 解析最大允许上传的大小.
	 */
	protected void parseMaxSize() {
		String maxSizeString = this.uploadPreferenceProperties
				.getProperty(MAX_SIZE_KEY);
		this.maxSizeInByte = DEFAULT_MAX_SIZE;
		if (null != maxSizeString) {
			this.maxSizeInByte = Long.parseLong(maxSizeString);
		}
	}

	/**
	 * 解析文件储存位置.
	 */
	protected void parseStore() {
		this.store = this.uploadPreferenceProperties.getProperty(STORE_KEY);
		Assert.hasText(store, "必须指定文件储存位置");
	}

	private Properties stringToProperties(String preferenceDefintion) {
		String propertiesString = preferenceDefintion.replaceAll(";",
				SystemUtils.LINE_SEPARATOR);
		Properties uploadPreferenceProperties = new Properties();
		InputStream is = new ByteArrayInputStream(propertiesString.getBytes());
		try {
			uploadPreferenceProperties.load(is);
		} catch (IOException e) {
			throw new RuntimeException("无法解析上传属性", e);
		} finally {
			IOUtils.closeQuietly(is);
		}
		return uploadPreferenceProperties;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.upload.UploadPreference#getStore()
	 */
	public String getStore() {
		return store;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.upload.UploadPreference#getMaxSizeInByte()
	 */
	public long getMaxSizeInByte() {
		return maxSizeInByte;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see itsm.isperp.upload.UploadPreference#getAllowedTypes()
	 */
	public String[] getAllowedTypes() {
		return allowedTypes;
	}

	protected Properties getUploadPreferenceProperties() {
		return uploadPreferenceProperties;
	}

	private String store = null;
	private long maxSizeInByte = 0L;
	private String[] allowedTypes = null;
	private Properties uploadPreferenceProperties = null;

}
